# frozen_string_literal: true

module Wpxf
  def self.modules_path
    File.join(Wpxf.app_path, 'lib', 'wpxf', 'modules')
  end

  def self.custom_modules_path
    File.join(Wpxf.home_directory, 'modules')
  end

  def self.payloads_path
    File.join(Wpxf.app_path, 'lib', 'wpxf', 'payloads')
  end

  def self.build_module_list(namespace, source_folders = [])
    modules = namespace.constants.select do |c|
      namespace.const_get(c).is_a? Class
    end

    modules.map do |m|
      klass = namespace.const_get(m)
      filename = klass.new.method(:initialize).source_location[0]

      # Remove any source folders from the path and store the
      # relative path that will be used in the CLI.
      source_folders.each do |source_folder|
        filename = filename.sub(source_folder, '')
      end

      {
        class: klass,
        name: filename.sub(/^\//, '').sub(/\.rb$/, '')
      }
    end
  end

  def self.load_module(path)
    mod = Wpxf::Models::Module.first(path: path)
    raise "\"#{path}\" is not a valid module" if mod.nil?
    Object.const_get(mod.class_name).new
  end

  def self.load_custom_modules
    custom_modules_path = File.join(Wpxf.home_directory, 'modules', '**', '*.rb')
    Dir.glob(custom_modules_path).each { |p| load p }
  end

  module Auxiliary
    def self.module_list
      Wpxf.build_module_list(Wpxf::Auxiliary, [Wpxf.modules_path, Wpxf.custom_modules_path])
    end
  end

  module Exploit
    def self.module_list
      Wpxf.build_module_list(Wpxf::Exploit, [Wpxf.modules_path, Wpxf.custom_modules_path])
    end
  end

  module Payloads
    def self.payload_count
      payloads = Wpxf::Payloads.constants.select do |c|
        Wpxf::Payloads.const_get(c).is_a? Class
      end

      payloads.size
    end

    def self.payload_list
      @@payloads ||= Wpxf.build_module_list(Wpxf::Payloads, [Wpxf.payloads_path])
    end

    def self.load_payload(name)
      payload = payload_list.find { |p| p[:name] == name }
      raise "\"#{name}\" is not a valid payload" if payload.nil?
      payload[:class].new
    end
  end
end

require_rel 'modules/auxiliary'
require_rel 'modules/exploit'
require_rel 'payloads'

Wpxf.load_custom_modules
